<?php

namespace app\common\controller;

use think\Db;
use think\Log;

/**
 * 余额操作类
 * Class Balance
 * @package app\common\controller
 */
class Balance
{
	use \app\common\traits\ToolTrait;
	/**
	 * 实例对象
	 * @var object
	 */
	protected static $instance;

	/**
	 * 默认配置
	 * @var array
	 */
	protected $config = [
		"prefix" 		=> "fd_",
		"user" 			=> "user",
		"balance"		=> "balance",
		"typs"			=> "balance_type",
		"log"			=> "balance_log",
	];

	/**
	 * 实例化
	 */
	public static function instance()
	{
		if (is_null(self::$instance)) {
			self::$instance = new static();
		}
		return self::$instance;
	}

	/**
	 * 查看
	 * @param int $uid 代理ID
	 * @return boolean
	 */
	public function check($uid = 0)
	{
		if (!empty($uid)) {
			$check = Db::name($this->config["balance"])
				->where("main_id = " . $uid)
				->count();
			if ($check) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 获取
	 * @param int $uid 用户ID
	 */
	public function get($uid = 0)
	{
		$balance = 0;
		if ($uid) {
			$where = "";
			$where = "main_id = " . $uid;
			$check = $this->check($uid);
			if ($check) {
				$balance = Db::name($this->config["balance"])->where($where)->value("money");
			}
		}
		return $balance;
	}

	/**
	 * 变更操作
	 * 
	 * @param array $option 
	 *  传参规则
	 *	option = [
	 *		"uid"		=> "0", // 用户ID
	 *		"typs"		=> "string", // 变更类型 
	 *		"isChg" 	=> "1", 变更状态 // 1 收入 2 支出  
	 *		"remark" 	=> "变更备注",	// 备注    
	 *		"chgAmt" 	=> "0",	// 变更金额
	 *	]
	 * @return boolean
	 */
	public function changeOpera($option = [])
	{
		$prams = ["uid", "isChg", "chgAmt", "typs"];
		$checkPrams = $this->checkParams($option, $prams);
		if ($checkPrams) {
			if (in_array($option["isChg"], [1, 2])) {
				Db::startTrans();
				try {
					$check = false;
					$after = 0;
					$org = $this->get($option["uid"]);
					switch ($option["isChg"]) {
						case 1:
							$r = $this->add($option["uid"], $option["chgAmt"]);
							if ($r) $check = true;
							$after = bcadd((string)$org, (string)$option["chgAmt"], 2);
							break;
						case 2:
							if (is_numeric($option["chgAmt"]) && $org >= $option["chgAmt"]) {
								$r = $this->sub($option["uid"], $option["chgAmt"]);
								if ($r) $check = true;
								$after = bcsub((string)$org, (string)$option["chgAmt"], 2);
							}
							break;
					}
					if ($check) {
						$option["orig"] = $org;
						$option["after"] = $after;
						$ret = $this->cords($option);
						if ($ret) {
							Db::commit();
							return true;
						}
					}
				} catch (\Exception $e) {
					Db::rollback();
					return false;
				}
			} else {
				return false;
			}
		} else {
			return false;
		}
	}

	/**
	 * 加
	 * @param int $uid 用户ID
	 * @param float|string $money
	 * @return boolean
	 */
	public function add($uid = 0, $money = "")
	{
		if (!empty($uid)) {
			$data = [];
			$update = [];
			$check = $this->check($uid);
			if ($check) {
				$update["money"] = Db::raw("money" . " + " . $money);
				$ret = Db::name($this->config["balance"])
					->where("main_id = " . $uid)
					->update($update);
				if ($ret) {
					return true;
				}
			} else {
				$data = [
					"main_id" 	=> $uid,
					"money" 	=> $money,
					"main_type" => $this->_get_user_type($uid)
				];
				$ret = Db::name($this->config["balance"])->insert($data);
				if ($ret) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * 减
	 * @param int $uid 用户ID
	 * @param float|string $money
	 * @return boolean
	 */
	public function sub($uid = 0, $money = "")
	{
		if (!empty($uid)) {
			$update = [];
			$check = $this->check($uid);
			if ($check) {
				$update["money"] = Db::raw("money" . " - " . $money);
				$ret = Db::name($this->config["balance"])->where("main_id = " . $uid)->update($update);
				if ($ret) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 *  余额变更记录
	 *  传参规则
	 *	option = [
	 *		"uid"		=> "0", // 收入 或 支出 代理ID
	 *		"typs"		=> "string", // 变更类型
	 *		"isChg" 	=> "0", // 1 收入 2 支出
	 *		"remark" 	=> "x",	// 备注  => 没有备注传空字符串
	 *		"orig"		=> "0", // 原余额    => 默认传0
	 *		"chgAmt" 	=> "0",	// 变更金额
	 *		"after"		=> "0"  // 变更后余额
	 *	]
	 * @return int|boolean
	 */
	public function cords($option = [])
	{
		if (is_array($option) && !empty($option)) {
			$store_arr = [];
			$check_prams = ["uid", "typs", "isChg", "chgAmt"];
			if ($this->checkParams($option, $check_prams)) {
				$store_arr = [
					"main_id" 			=> $option["uid"], 		// 收入|支出 用户ID
					"balance_type" 		=> $option["typs"], 	// 变更类型 
					"change_state"		=> $option["isChg"],	// 1 收入 2 支出
					"mome" 				=> $option["remark"],	// 备注
					"before" 			=> $option["orig"],		// 变更金额
					"money" 			=> $option["chgAmt"],	// 变更金额
					"after" 			=> $option["after"],	// 变更后余额
					"times"				=> strtotime(date("Y-m-d"), time()),
					"create_time" 		=> time(),
				];
				$id = Db::name($this->config["log"])->insertGetId($store_arr);
				if ($id) {
					return $id;
				}
			}
		}
		return false;
	}


	/**
	 * 获取-用户类型
	 * @param int $uid 用户ID
	 * @return int|boolean
	 */
	public function _get_user_type($uid)
	{
		if (!$uid) {
			return false;
		}
		return Db::name($this->config["user"])->where("id", $uid)->value("is_typs");
	}
}
